/*
 * @Date: 2022-03-09 08:26:23
 * @Version: 1.0.0
 * @Author: minichen
 * @Description: marker
 * @FilePath: \bmap-libs\src\plugin\marker.js
 * @LastEditTime: 2022-03-16 21:34:45
 * @LastEditors: minichen
 */
import customOverlay from './customOverlay';

export default function () {
  const BMapGLLib = (window.BMapGLLib = window.BMapGLLib || {});

  let BMap = window.BMap || window.BMapGL;

  if (!BMap) {
    console.error('bamp-libs: BMap or BMapGL is not found!');
    return;
  }

  const CustomOverlay = customOverlay(BMap);

  function Marker(point, content, options) {
    if (!point || !content || !(point instanceof BMap.Point)) {
      console.error('bamp-libs: Params error!');
      return null;
    }

    const _options = {
      zIndex: 1,
      offset: new BMap.Size(0, 0),
      className: '',
      pane: 'markerPane',
    };

    // 参数
    this._point = point;
    this._content = content;
    this._options = { ..._options, ...options };

    // 状态
    this._initialized = false; // 是否初始化
    this._removed = false; // 是否移除
    this._needUpdate = false; // 是否需要更新

    // 属性
    this._map = null; // 地图实例
    this._container = null; // dom节点
    this._size = null; // dom尺寸
    this._popup = null; // 绑定的popup实例

    // 增强子类
    CustomOverlay.call(this);
  }

  Marker.prototype = Object.create(CustomOverlay.prototype);
  Marker.prototype.constructor = Marker;

  Marker.prototype.initialize = function (map) {
    // 参数有误
    if (this._initialized === undefined) return;

    // 创建marker
    const marker = document.createElement('div');
    marker.className = ('bmap-marker ' + this._options.className).trim();
    marker.style.position = 'absolute';

    this._map = map;
    this._container = marker;

    // 设置层级
    this.setZIndex(this._options.zIndex);
    // 将自定义marker内容添加到marker节点中
    this._appendContainerContent();
    // 添加事件
    this._patchEventHandle(this._bindEvent);
    // 监听clearoverlays事件
    this._addClearoverlaysEvent();

    // 将marker添加到dom中
    this._addDom();
    // 获取元素尺寸
    this._getContainerSize();

    this._initialized = true;

    // 如果在marker添加到地图前绑定了popup，此时初始化popup
    if (this._popup) {
      this._addPopup();
    }

    return marker;
  };

  Marker.prototype.draw = function () {
    if (!this._initialized) return;

    // 移除后重新添加节点
    if (this._removed) {
      // 重新添加节点
      this._addDom();
      // 重新绑定事件
      this._patchEventHandle(this._bindEvent);
      // 重新监听clearoverlays事件
      this._addClearoverlaysEvent();

      // 重新添加popup
      if (this._popup) {
        this._map.addOverlay(this._popup);
      }

      this._removed = false;
    }

    // 检测更新，更新尺寸以及popup锚点
    if (this._needUpdate && this.isVisible()) {
      this._getContainerSize();

      if (this._popup) {
        this._setPopupAnchor();
      }

      this._needUpdate = false;
    }

    // 调整位置
    const pixel = this._map.pointToOverlayPixel(this._point);
    this._container.style.left = pixel.x - this._size.width / 2 + this._options.offset.width + 'px';
    this._container.style.top = pixel.y - this._size.height + this._options.offset.height + 'px';
  };

  Marker.prototype.remove = function () {
    if (!this._initialized || this._removed) return;

    // 移除clearoverlays事件
    this._removeClearoverlaysEvent();
    // 移除节点事件
    this._patchEventHandle(this._unbindEvent);
    // 移除popup
    this._removePopup();
    // 移除节点
    this._removeDom();

    this._removed = true;
  };

  /**
   * @description: 更新
   * @param {*}
   * @return {*}
   */
  Marker.prototype.update = function () {
    this._needUpdate = true;
    this._draw();
  };

  /**
   * @description: 重写show方法
   * @param {*}
   * @return {*}
   */
  Marker.prototype.show = function () {
    BMap.Overlay.prototype.show.call(this);

    // 绑定的popup伴随显示
    if (this._popup) {
      this._popup._followShow();
    }

    if (this._needUpdate) {
      this._draw();
    }
  };

  /**
   * @description: 重写hide方法
   * @param {*}
   * @return {*}
   */
  Marker.prototype.hide = function () {
    BMap.Overlay.prototype.hide.call(this);

    // 绑定的popup伴随隐藏
    if (this._popup) {
      this._popup._followHide();
    }
  };

  /* ----------------------------------Popup--------------------------------------- */

  /**
   * @description: 绑定popup
   * @param {*} popup
   * @return {*}
   */
  Marker.prototype.bindPopup = function (popup) {
    if (!popup) return;

    this._popup = popup;
    this._addPopup();
  };

  /**
   * @description: 添加popup到dom
   * @param {*}
   * @return {*}
   */
  Marker.prototype._addPopup = function () {
    if (!this._initialized) return;

    this._setPopupAnchor();
    this._popup.setPoint(this._point);
    this._map.addOverlay(this._popup);
  };

  /**
   * @description: 设置popup锚点
   * @param {*}
   * @return {*}
   */
  Marker.prototype._setPopupAnchor = function () {
    this._popup._setAnchor(new BMap.Size(0, -this._size.height));
  };

  /**
   * @description: 移除popup
   * @param {*}
   * @return {*}
   */
  Marker.prototype._removePopup = function () {
    if (!this._initialized) return;

    if (this._popup && this._map.getOverlays().some((v) => v === this._popup)) {
      this._map.removeOverlay(this._popup);
    }
  };

  /**
   * @description: 解绑popup
   * @param {*}
   * @return {*}
   */
  Marker.prototype.unbindPopup = function () {
    if (!this._popup) return;

    this._removePopup();
    this._popup = null;
  };

  /**
   * @description: 获取popup
   * @param {*}
   * @return {*}
   */
  Marker.prototype.getPopup = function () {
    return this._popup;
  };

  /**
   * @description: 打开popup
   * @param {*}
   * @return {*}
   */
  Marker.prototype.openPopup = function () {
    if (!this._popup) return;
    this._popup.show();
  };

  /**
   * @description: 关闭popup
   * @param {*}
   * @return {*}
   */
  Marker.prototype.closePopup = function () {
    if (!this._popup) return;
    this._popup.hide();
  };

  /**
   * @description: popup是否打开
   * @param {*}
   * @return {*}
   */
  Marker.prototype.isPopupOpen = function () {
    return this._popup ? this._popup.isVisible() : false;
  };

  BMapGLLib.Marker = Marker;
}
